package com.dferreira.languagesteach.data_adapters;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.dferreira.languagesteach.LanguagesTeachApplication;
import com.dferreira.languagesteach.R;
import com.dferreira.languagesteach.constants.Constants;
import com.dferreira.languagesteach.custom_items.UITableViewCellOnSection;
import com.dferreira.languagesteach.data_models.Exercise;
import com.dferreira.languagesteach.data_models.Section;
import com.dferreira.languagesteach.data_parsers.XMLWorkoutParser;
import com.dferreira.languagesteach.data_adapters.generic.NavigationAdapter;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class WorkoutsAdapter extends NavigationAdapter implements
        OnClickListener {

    private String languagesInstalledFolder;


    /**
     * @param context reference to the which the dataSource belongs
     */
    public WorkoutsAdapter(Context context, String packageInstalledFolder) {
        super(context, packageInstalledFolder);
    }

    /**
     * @param languagesInstalledFolder folder where the languages were installed
     * @return false   -> some error happened
     * true    -> everything was alright
     */
    public boolean buildDataSet(String languagesInstalledFolder) {
        // Local variables
        Iterator<Section> sections;
        this.languagesInstalledFolder = languagesInstalledFolder;

        // Build from ExercisesCells
        sections = parseWorkoutScreenXML();
        if (sections == null) {
            return false;
        }

        buildWorkoutList(sections);
        dataSetWellConstructed();
        return true;
    }

    /**
     * Parse the workout.xml file from some package
     *
     * @return an section iterator
     */
    private Iterator<Section> parseWorkoutScreenXML() {
        // Local variables
        SAXParserFactory spf;
        SAXParser sp;
        XMLReader xr;
        XMLWorkoutParser xmlExercisesParser;
        FileInputStream inputStream;
        File file;
        String workoutFileName;

        workoutFileName = Constants.WORKOUT_FILE_NAME;
        try {
            // parsing from XML file
            spf = SAXParserFactory.newInstance();
            sp = spf.newSAXParser();
            xr = sp.getXMLReader();
            xmlExercisesParser = new XMLWorkoutParser();
            xr.setContentHandler(xmlExercisesParser);
            file = new File(languagesInstalledFolder + File.separator
                    + workoutFileName);
            inputStream = new FileInputStream(file);
            xr.parse(new InputSource(inputStream));
            inputStream.close();
            // Build from ExercisesCells
            return xmlExercisesParser.getWorkout().getSections().iterator();
        } catch (FileNotFoundException e) {
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Build from workout Cells sections/exercises
     *
     * @param sections models available the workout.xml
     */
    private void buildWorkoutList(Iterator<Section> sections) {
        String exerciseIconsFolder;
        String iconsExtension;

        exerciseIconsFolder = Constants.EXERCISE_ICONS_FOLDER;
        iconsExtension = Constants.ICONS_EXTENSION;

        while (sections.hasNext()) {
            UITableViewCellOnSection tmpCell;
            Section section = sections.next();
            tmpCell = new UITableViewCellOnSection();
            tmpCell.setTextLabel("");
            tmpCell.setTag(section.getPrefix());
            tmpCell.setSection(true);
            tmpCell.setImageView(languagesInstalledFolder + File.separator
                    + exerciseIconsFolder + File.separator
                    + section.getPrefix() + iconsExtension);
            add(tmpCell);
            for (Exercise refExercise : section.getExercisesLst()) {
                tmpCell = new UITableViewCellOnSection();
                tmpCell.setTextLabel(refExercise.getTitle());
                tmpCell.setTag(refExercise.get_class());
                tmpCell.setSection(false);
                add(tmpCell);
            }
        }
    }


    /**
     * @param position    The position of the item within the adapter's data set of the item whose view we want.
     * @param convertView The old view to reuse, if possible. Note: You should check that this view is non-null and
     *                    of an appropriate type before using. If it is not possible to convert this view to display
     *                    the correct data, this method can create a new view. Heterogeneous lists can specify their
     *                    number of view types, so that this View is always of the right type (see getViewTypeCount()
     *                    and getItemViewType(int)).
     * @param parent      The parent that this view will eventually be attached to
     * @return the view to be rendered by system inflate a costumed view that
     * provided a image/label pair set the label from the row set the image from
     * the row set the tag which identify the row set the listener from the row
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        UITableViewCellOnSection item;
        View row;
        Drawable sectionImg;
        ImageView imageView;


        item = (UITableViewCellOnSection) getItem(position);

        LayoutInflater inflater = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (item.getSection()) {
            // Section divisor
            sectionImg = item.getImageView();
            row = inflater.inflate(R.layout.table_view_cell_group, parent,
                    false);
            if (row == null) {
                return null;
            }
            imageView = (ImageView) row.findViewById(R.id.imageView);
            imageView.setVisibility(android.view.View.VISIBLE);
            imageView.setImageDrawable(sectionImg);
            return row;
        } else {
            return super.getView(position, convertView, parent);
        }
    }

    /**
     * When some of the workout items is click is pushed a new activity that was gotten by reflection
     *
     * @param v view of the kind of workout pressed
     */
    @Override
    public void onClick(View v) {
        String controllersPrefix;
        String workoutTag;

        controllersPrefix = Constants.ACTIVITIES_PREFIX;
        workoutTag = (String) v.getTag();
        LanguagesTeachApplication.getApplicationState().setWorkout(workoutTag);
        pushExerciseActivity(controllersPrefix + workoutTag);
    }

    /**
     * Restore last workout viewed by user
     */
    public void restorePath() {
        String controllersPrefix;
        String workoutTag;

        controllersPrefix = Constants.ACTIVITIES_PREFIX;
        workoutTag = LanguagesTeachApplication.getApplicationState().getWorkout();

        if (this.doSessionRestore()) {
            pushExerciseActivity(controllersPrefix + workoutTag);
        }
    }
}
